//    Dhammapada PSP
//    Copyright (C) 2007 Sakya
//    sakya_tg@yahoo.it
//
//    This program is free software; you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation; either version 2 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program; if not, write to the Free Software
//    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#include <pspkernel.h>
#include <pspsdk.h>
#include <psppower.h>
#include <stdio.h>
#include <unistd.h>
#include <oslib/oslib.h>

#include "main.h"
#include "languages.h"
#include "dhammapada.h"
#include "mainmenu.h"
#include "index.h"
#include "options.h"
#include "viewcategory.h"
#include "about.h"

PSP_MODULE_INFO("dhammapada", 0, 1, 0);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);
PSP_HEAP_SIZE_KB(22000);

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Globals:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
char ebootDirectory[262] = "";
struct settings *userSettings;
SceKernelUtilsMt19937Context ctx;
    
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Callbacks:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* Exit callback */
int exit_callback(int arg1, int arg2, void *common) {
    oslQuit();
    return 0;
}

/* Callback thread */
int CallbackThread(SceSize args, void *argp) {
    int cbid;

    cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
    sceKernelRegisterExitCallback(cbid);
    sceKernelSleepThreadCB();
    return 0;
}

/* Sets up the callback thread and returns its thread id */
int SetupCallbacks(void) {
    int thid = 0;

    thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, PSP_THREAD_ATTR_USER, 0);
    if(thid >= 0)
        sceKernelStartThread(thid, 0, 0);
    return thid;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Critical error:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void errorLoadImage(char *imageName){
    char errMsg[300];
    snprintf(errMsg, sizeof(errMsg), "Cannot load image/font: %s", imageName);
    oslMessageBox(errMsg, "Critical error",  oslMake3Buttons(OSL_KEY_CROSS, OSL_MB_QUIT , 0, 0, 0, 0));
    oslQuit();
}


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Debug message with messageBox:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void debugMessageBox(char *message){
    oslMessageBox(message, "Debug",  oslMake3Buttons(OSL_KEY_CROSS, OSL_MB_OK , 0, 0, 0, 0));
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Init OSLib:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int initOSLib(){
    oslInit(0);
    oslInitGfx(OSL_PF_8888, 1);
    oslInitConsole();
    oslInitAudio();
    oslSetQuitOnLoadFailure(0);
    //Init input
    oslSetKeyAutorepeatInit(40);
    oslSetKeyAutorepeatInterval(10);
    return 0;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// End OSLib:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int endOSLib(){
    oslEndGfx();
    oslQuit();
    return 0;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// getRandomNumber: generates a random number between min and max:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int getRandomNumber(int min, int max){
    u32 rnd = sceKernelUtilsMt19937UInt(&ctx);
    rnd = min + rnd % (max - min + 1);
    return rnd;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Main:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int main(){
    char buffer[262] = "";
    int currentMode = MODE_MAINMENU;
    //Init:
	SetupCallbacks();
    initOSLib();

    //Seed for random:
    sceKernelUtilsMt19937Init(&ctx, time(NULL));
    
	//Full name for settings' file:
    getcwd(ebootDirectory, 256);
	strcpy(buffer, ebootDirectory);
	if (buffer[strlen(buffer)-1] != '/')
		strcat(buffer, "/");
	strcat(buffer, "settings");
	//Carico le opzioni:
	if (!SETTINGS_load(buffer))
		userSettings = SETTINGS_get();
	else{
        userSettings = SETTINGS_default();
		strcpy(userSettings->fileName, buffer);
    }
    strcpy(userSettings->ebootPath, ebootDirectory);
    
    initMenu(userSettings);
    
    //Load language file:
    sprintf(buffer, "%s/data/", userSettings->ebootPath);
    langLoadList(buffer);
    sprintf(buffer, "%s/data/%s/lang.txt", userSettings->ebootPath, userSettings->lang);
    langLoad(buffer);
    
    //Loading screen:
    sprintf(buffer, "%s/images/font.oft", userSettings->ebootPath);
    OSL_FONT *font = oslLoadFontFile(buffer);
    if (!font)
        errorLoadImage(buffer);
    oslStartDrawing();
    oslSetBkColor(RGBA(0, 0, 0, 0));
    oslSetTextColor(RGBA(255, 255, 255, 255));
    oslSetFont(font);
    oslDrawString(5, 270 - font->charHeight, langGetString("LOADING"));
	oslEndDrawing();
	oslSyncFrame();
	oslAudioVSync();
	oslDeleteFont(font);

    //GetIndex:
    loadCategoriesIndexOriginal();
    loadCategoriesIndex(userSettings->lang);
    
    scePowerSetClockFrequency(50, 50, 111);
    while(!osl_quit){
        switch (currentMode){
            case (MODE_MAINMENU):
                currentMode = mainMenu(userSettings);
                break;
            case (MODE_OPTIONS):
                currentMode = optionsMenu(userSettings);
                break;
            case (MODE_INDEX):
                currentMode = indexMenu(userSettings);
                break;
            case (MODE_VIEWCATEGORY):
                currentMode = viewCategory(userSettings);
                break;
            case (MODE_ABOUT):
                currentMode = about(userSettings);
                break;
            default:
                oslQuit();
                break;
        }
    }
	//Salvo le opzioni:
	SETTINGS_save(userSettings);
    endOSLib();
	sceKernelExitGame();
    return 0;
}

